/**
 * @file mainwindow.cpp
 * @brief 主窗口类实现文件
 *
 * 实现应用程序主界面的所有功能：
 * - 界面布局和组件创建
 * - 用户操作处理
 * - 组件间通信协调
 */

#include "mainwindow.h"  // 包含自定义头文件

// 包含Qt的各种GUI组件
#include <QMenuBar>      // 菜单栏
#include <QToolBar>      // 工具栏
#include <QStatusBar>    // 状态栏
#include <QFileDialog>   // 文件对话框
#include <QMessageBox>   // 消息框
#include <QVBoxLayout>   // 垂直布局
#include <QHBoxLayout>   // 水平布局
#include <QWidget>       // 窗口部件基类
#include <QLabel>        // 标签
#include <QPushButton>   // 按钮
#include <QAction>       // 动作

/**
 * @brief 构造函数
 * @param parent 父窗口指针
 *
 * 初始化流程：
 * 1. 设置窗口基本属性
 * 2. 创建算法引擎
 * 3. 构建用户界面
 * 4. 显示初始状态
 */
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , imageCanvas(nullptr)          // 初始化指针为空
    , controlPanel(nullptr)         // 初始化指针为空
    , inpaintingEngine(nullptr)     // 初始化指针为空
    , openButton(nullptr)           // 初始化指针为空
    , openAction(nullptr)           // 初始化指针为空
    , exitAction(nullptr)           // 初始化指针为空
    , penToolButton(nullptr)        // 初始化指针为空
    , rectToolButton(nullptr)       // 初始化指针为空
    , eraserToolButton(nullptr)     // 初始化指针为空
    , clearMaskButton(nullptr)      // 初始化指针为空
{
    // 设置窗口标题和初始大小
    setWindowTitle("图像修复系统");
    resize(1200, 800);  // 宽度1200像素，高度800像素

    // 初始化修复算法引擎 - 核心算法组件
    inpaintingEngine = new InpaintingEngine(this);

    // 构建用户界面
    createMenus();      // 创建菜单栏
    createToolbars();   // 创建工具栏
    createCentralWidget(); // 创建中央区域

    // 在状态栏显示就绪信息
    statusBar()->showMessage("就绪 - 请打开图像文件开始修复");
}

/**
 * @brief 创建菜单栏
 *
 * 构建应用程序的菜单系统：
 * - 文件菜单：打开、退出等操作
 * - 视图菜单：缩放控制等显示操作
 */
void MainWindow::createMenus()
{
    // 文件菜单
    QMenu *fileMenu = menuBar()->addMenu("文件");
    fileMenu->addAction("打开图像", QKeySequence::Open, this, &MainWindow::onOpenImage);
    fileMenu->addSeparator();  // 分隔线
    fileMenu->addAction("退出", QKeySequence::Quit, this, &MainWindow::onExit);

    // 视图菜单 - 图像显示控制
    QMenu *viewMenu = menuBar()->addMenu("视图");
    viewMenu->addAction("放大", QKeySequence::ZoomIn, this, [this]() {
        if (imageCanvas) imageCanvas->zoomIn();  // Lambda表达式调用画布放大
    });
    viewMenu->addAction("缩小", QKeySequence::ZoomOut, this, [this]() {
        if (imageCanvas) imageCanvas->zoomOut(); // Lambda表达式调用画布缩小
    });
    viewMenu->addAction("重置缩放", QKeySequence("Ctrl+0"), this, [this]() {
        if (imageCanvas) imageCanvas->resetZoom(); // 重置缩放比例
    });
}

/**
 * @brief 创建工具栏
 *
 * 构建快速访问工具栏，包含常用功能按钮：
 * - 文件操作按钮
 * - 绘制工具按钮
 * - 蒙版操作按钮
 */
void MainWindow::createToolbars()
{
    QToolBar *mainToolbar = addToolBar("主工具栏");

    // 文件操作按钮
    openButton = new QPushButton("打开图像");
    mainToolbar->addWidget(openButton);

    mainToolbar->addSeparator();  // 添加分隔线

    // 绘图工具按钮
    penToolButton = new QPushButton("画笔");
    rectToolButton = new QPushButton("矩形");
    eraserToolButton = new QPushButton("橡皮擦");
    clearMaskButton = new QPushButton("清除蒙版");

    // 设置工具按钮为可选中状态（切换按钮）
    penToolButton->setCheckable(true);
    rectToolButton->setCheckable(true);
    eraserToolButton->setCheckable(true);
    penToolButton->setChecked(true);  // 默认选中画笔工具

    // 将按钮添加到工具栏
    mainToolbar->addWidget(penToolButton);
    mainToolbar->addWidget(rectToolButton);
    mainToolbar->addWidget(eraserToolButton);
    mainToolbar->addWidget(clearMaskButton);

    // ==================== 连接信号和槽 ====================
    // 文件操作信号
    connect(openButton, &QPushButton::clicked, this, &MainWindow::onOpenImage);

    // 工具选择信号
    connect(penToolButton, &QPushButton::clicked, this, &MainWindow::onPenToolSelected);
    connect(rectToolButton, &QPushButton::clicked, this, &MainWindow::onRectToolSelected);
    connect(eraserToolButton, &QPushButton::clicked, this, &MainWindow::onEraserToolSelected);

    // 蒙版操作信号
    connect(clearMaskButton, &QPushButton::clicked, this, &MainWindow::onClearMask);
}

/**
 * @brief 创建中央窗口部件
 *
 * 构建主窗口的中央区域布局：
 * - 左侧：图像画布（主要工作区）
 * - 右侧：控制面板（参数设置区）
 * 使用水平布局管理器，按4:1比例分配空间
 */
void MainWindow::createCentralWidget()
{
    // 创建中央窗口部件
    QWidget *centralWidget = new QWidget(this);
    QHBoxLayout *layout = new QHBoxLayout(centralWidget);  // 水平布局

    // 左侧：图像画布（占据主要空间）
    imageCanvas = new ImageCanvas(this);
    layout->addWidget(imageCanvas, 4);  // 权重为4，占据4/5空间

    // 右侧：控制面板（固定宽度区域）
    controlPanel = new ControlPanel(this);
    layout->addWidget(controlPanel, 1);  // 权重为1，占据1/5空间

    // 设置中央窗口部件
    setCentralWidget(centralWidget);

    // ==================== 连接控制面板信号 ====================
    // 画笔大小变化信号
    connect(controlPanel, &ControlPanel::brushSizeChanged,
            imageCanvas, &ImageCanvas::setBrushSize);

    // 开始修复信号
    connect(controlPanel, &ControlPanel::startInpainting,
            this, &MainWindow::onStartInpainting);
}

/**
 * @brief 打开图像文件槽函数
 *
 * 处理打开图像文件操作：
 * 1. 显示文件选择对话框
 * 2. 加载选中的图像文件
 * 3. 更新状态栏信息
 */
void MainWindow::onOpenImage()
{
    // 显示文件选择对话框
    QString fileName = QFileDialog::getOpenFileName(this,
                                                    "选择图像文件",
                                                    "",
                                                    "图像文件 (*.png *.jpg *.bmp *.jpeg)");

    if (!fileName.isEmpty()) {
        // 尝试加载图像文件
        if (imageCanvas->loadImage(fileName)) {
            // 加载成功，更新状态栏
            statusBar()->showMessage(QString("已加载: %1 - 请在图像上绘制需要修复的区域").arg(fileName));
        } else {
            // 加载失败，显示错误消息
            QMessageBox::warning(this, "错误", "无法加载图像文件！");
            statusBar()->showMessage("加载图像失败");
        }
    }
}

/**
 * @brief 退出应用程序槽函数
 */
void MainWindow::onExit()
{
    close();  // 关闭主窗口，触发应用程序退出
}

/**
 * @brief 选择画笔工具槽函数
 *
 * 切换工具状态并更新界面：
 * - 设置画笔按钮为选中状态
 * - 取消其他工具按钮的选中状态
 * - 通知画布切换工具
 */
void MainWindow::onPenToolSelected()
{
    // 更新按钮选中状态
    penToolButton->setChecked(true);
    rectToolButton->setChecked(false);
    eraserToolButton->setChecked(false);

    // 通知画布切换工具
    imageCanvas->setCurrentTool(ImageCanvas::Pen);

    // 更新状态栏提示
    statusBar()->showMessage("已选择画笔工具 - 在图像上绘制修复区域");
}

/**
 * @brief 选择矩形工具槽函数
 */
void MainWindow::onRectToolSelected()
{
    penToolButton->setChecked(false);
    rectToolButton->setChecked(true);
    eraserToolButton->setChecked(false);
    imageCanvas->setCurrentTool(ImageCanvas::Rectangle);
    statusBar()->showMessage("已选择矩形工具 - 绘制矩形修复区域");
}

/**
 * @brief 选择橡皮擦工具槽函数
 */
void MainWindow::onEraserToolSelected()
{
    penToolButton->setChecked(false);
    rectToolButton->setChecked(false);
    eraserToolButton->setChecked(true);
    imageCanvas->setCurrentTool(ImageCanvas::Eraser);
    statusBar()->showMessage("已选择橡皮擦工具 - 擦除不需要修复的区域");
}

/**
 * @brief 清除蒙版槽函数
 *
 * 清除所有绘制的修复区域，恢复到初始状态
 */
void MainWindow::onClearMask()
{
    imageCanvas->clearMask();
    statusBar()->showMessage("已清除所有蒙版区域");
}

/**
 * @brief 析构函数
 *
 * 清理动态分配的资源
 * 注意：由于使用了Qt的父子对象机制，大部分子对象会自动销毁
 * 这里显式删除是为了代码清晰性和特殊情况处理
 */
MainWindow::~MainWindow()
{
    // 由于Qt父子对象机制，这些对象会自动销毁
    // 但显式删除可以确保销毁顺序和资源清理

    delete imageCanvas;        // 删除图像画布
    delete controlPanel;       // 删除控制面板
    delete inpaintingEngine;   // 删除算法引擎

    // 删除动态创建的按钮对象
    delete openButton;
    delete penToolButton;
    delete rectToolButton;
    delete eraserToolButton;
    delete clearMaskButton;
}

/**
 * @brief 开始修复槽函数
 *
 * 执行图像修复的核心流程：
 * 1. 检查前置条件（图像加载、蒙版绘制）
 * 2. 获取算法参数
 * 3. 调用修复算法引擎
 * 4. 显示修复结果
 * 5. 更新用户界面状态
 */
void MainWindow::onStartInpainting()
{
    // ==================== 前置条件检查 ====================

    // 检查是否有图像加载
    if (imageCanvas->getOriginalImage().empty()) {
        QMessageBox::warning(this, "警告", "请先打开图像文件！");
        statusBar()->showMessage("错误：未加载图像");
        return;
    }

    // 检查是否有绘制修复区域
    cv::Mat mask = imageCanvas->getMask();
    if (mask.empty() || cv::countNonZero(mask) == 0) {
        QMessageBox::warning(this, "警告", "请先在图像上绘制需要修复的区域！");
        statusBar()->showMessage("错误：未绘制修复区域");
        return;
    }

    // ==================== 算法参数准备 ====================

    // 获取当前选择的算法类型
    QString algorithm = controlPanel->getSelectedAlgorithm();
    InpaintingEngine::Algorithm algoType = InpaintingEngine::FMM;  // 默认使用FMM

    // 根据算法选择更新界面状态
    if (algorithm == "FMM") {
        statusBar()->showMessage("正在使用快速行进法(FMM)进行修复...");
    } else if (algorithm == "Criminisi") {
        // 算法待实现，暂时使用FMM替代
        QMessageBox::information(this, "提示", "Criminisi算法开发中，暂时使用FMM算法");
        statusBar()->showMessage("Criminisi算法开发中，使用FMM算法进行修复...");
    } else {
        // 深度学习算法待实现，暂时使用FMM替代
        QMessageBox::information(this, "提示", "深度学习算法开发中，暂时使用FMM算法");
        statusBar()->showMessage("深度学习算法开发中，使用FMM算法进行修复...");
    }

    // ==================== 执行修复算法 ====================

    // 显示开始修复提示
    QMessageBox::information(this, "修复开始",
                             QString("开始使用%1算法进行修复\n修复过程可能需要几秒钟").arg(algorithm));

    // 调用修复算法引擎执行修复
    cv::Mat result = inpaintingEngine->inpaint(
        imageCanvas->getOriginalImage(),  // 原始图像
        mask,                             // 修复蒙版
        algoType                          // 算法类型
        );

    // ==================== 结果显示 ====================

    // 在画布上显示修复结果
    imageCanvas->showResult(result);

    // 更新状态栏
    statusBar()->showMessage(QString("使用%1算法修复完成").arg(algorithm));

    // 显示完成提示
    QMessageBox::information(this, "修复完成",
                             "图像修复完成！\n您可以选择其他区域继续修复或打开新图像。");
}
